/******************************************************************************
* Copyright (C) 2017, Huada Semiconductor Co.,Ltd All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer:
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACOOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file main.c
 **
 ** A detailed description is available at
 ** @link Sample Group Some description @endlink
 **
 **   - 2017-10-31  1.0  Lux First version
 **
 ******************************************************************************/

/******************************************************************************
 * Include files
 ******************************************************************************/
#include "hc32l110.h"
#include "uart.h"
#include "bt.h"
#include "lpm.h"
#include "gpio.h"
#include "adc.h"



/******************************************************************************
 * Local pre-processor symbols/macros ('#define')                            
 ******************************************************************************/
#define     T1_PORT                 (3)
#define     T1_PIN                  (3)

#define SK_SW2_INIT()       Gpio_InitIO(3, 3, GpioDirIn);
#define SK_SW2_GET()        Gpio_GetIO(3,3)

/******************************************************************************
 * Global variable definitions (declared in header file with 'extern')
 ******************************************************************************/

/******************************************************************************
 * Local type definitions ('typedef')                                         
 ******************************************************************************/

/******************************************************************************
 * Local function prototypes ('static')
 ******************************************************************************/

/******************************************************************************
 * Local variable definitions ('static')                                      *
 ******************************************************************************/

/******************************************************************************
 * Local pre-processor symbols/macros ('#define')                             
 ******************************************************************************/

uint8_t u8RxData[2]={0x55,0x00};
uint8_t u8RxFlg=0;
uint8_t CheckFlg=0;
void RxIntCallback(void)
{
    u8RxData[1]=M0P_UART1->SBUF;
	u8RxFlg = 1;
}

void ErrIntCallback(void)
{
  
}


/*******************************************************************************
 * Function implementation - global ('extern') and local ('static')
 ******************************************************************************/

/*******************************************************************************
 * BT1中断服务函数
 ******************************************************************************/
void Bt1Int(void)
{
    if (TRUE == Bt_GetIntFlag(TIM1))
    {
        Bt_ClearIntFlag(TIM1);
        //u32BtTestFlag = 0x02;
    }
}

uint32_t cnt = 0;
/*******************************************************************************
 * BT定时功能测试 （重载模式）
 ******************************************************************************/
en_result_t BtTimerTest(void)
{
    stc_bt_config_t   stcConfig;
    en_result_t       enResult = Error;
    uint16_t          u16ArrData = 0x8000;
    uint16_t          u16InitCntData = 0xC000;
    
    stcConfig.pfnTim1Cb = Bt1Int;
    //P25设置为门控使能IO
    Gpio_SetFunc_TIM1_GATE_P25();
        
    stcConfig.enGateP = BtPositive;
    stcConfig.enGate  = BtGateDisable;
    stcConfig.enPRS   = BtPCLKDiv16;
    stcConfig.enTog   = BtTogDisable;
    stcConfig.enCT    = BtTimer;
    stcConfig.enMD    = BtMode2;
    //Bt初始化
    if (Ok != Bt_Init(TIM1, &stcConfig))
    {
        enResult = Error;
    }
    
    //TIM1中断使能
    Bt_ClearIntFlag(TIM1);
    Bt_EnableIrq(TIM1);
    EnableNvic(TIM1_IRQn, 3, TRUE);
    
    //设置重载值和计数值，启动计数
    Bt_ARRSet(TIM1, u16ArrData);
    Bt_Cnt16Set(TIM1, u16InitCntData);
    Bt_Run(TIM1);
    
    //此处进入中断……
    while(1)
    {
        //判断是否第二次进入中断
        //if (0x02 == u32BtTestFlag)
        //{
        //    u32BtTestFlag = u32BtTestFlag & (~0x02);
        //    if (1 == u32Cnt)
        //    {
        //        Bt_Stop(TIM1);
        //        enResult = Ok;
        //        break;
        //    }
        //    u32Cnt++;
        //}
			cnt++;
    }    
    
    return enResult;
}



void clk16m_init(){
    //RCH 16MHz
    Clk_SwitchTo(ClkRCL);
    Clk_SetRCHFreq(ClkFreq16Mhz);
    Clk_SwitchTo(ClkRCH);
    //u32Val = Clk_GetHClkFreq();

}


void timer_test(){
    uint16_t timer=0;
    volatile uint32_t pclk=0;
	stc_clk_config_t stcClkCfg;
    
    stcClkCfg.enClkSrc  = ClkRCH;
    stcClkCfg.enHClkDiv = ClkDiv1;
    stcClkCfg.enPClkDiv = ClkDiv1;

	clk16m_init();
    Clk_Init(&stcClkCfg);
		pclk = Clk_GetHClkFreq();
		pclk = Clk_GetHClkFreq();  
    
    //打开GPIO、BT外设时钟
    Clk_SetPeripheralGate(ClkPeripheralGpio, TRUE);
    Clk_SetPeripheralGate(ClkPeripheralBt, TRUE);
       
    if(Ok != BtTimerTest())
    {
        //u8TestFlag |= 0x02;
    }

}


#define TEST_PIN_EX	(2)
void led_test(){
	//GPIO输入
   //配置P33为输入，P33外接SW2按键
 //  Gpio_InitIO(3, 3, GpioDirIn);
   //如果按键SW2按下，为低电平，则跳出循环继续执行程序
  // while (TRUE == Gpio_GetIO(3,3));   
  
   //GPIO输出
   //初始化外部GPIO P03为输出、上拉、开漏，P03端口外接LED3
   Gpio_InitIOExt(0, TEST_PIN_EX, GpioDirOut, TRUE, FALSE, TRUE, FALSE);
   //设置GPIO值（翻转）
   while (1)
   {
	   //输出高电平，LED3灭
	   Gpio_SetIO(0, TEST_PIN_EX, TRUE);
	   delay1ms(500);

	   //输出低电平，LED3亮
	   Gpio_SetIO(0, TEST_PIN_EX, FALSE);
	   delay1ms(500);
   }

}

/////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////// 
/******************************************************************************
 * Local pre-processor symbols/macros ('#define')
 ******************************************************************************/
#define TEST_PORT       (3)
#define TEST_PIN        (4)

void SysTick_Handler(void)
{
    static uint8_t u8Flag = TRUE;

    Gpio_SetIO(TEST_PORT, TEST_PIN, u8Flag);
    u8Flag = !u8Flag;
}

void SysTick_Test(void){
    volatile uint32_t u32Val = 0;
    stc_clk_systickcfg_t stcCfg;

    SK_SW2_INIT();
   // while (TRUE == SK_SW2_GET());

    Gpio_InitIO(TEST_PORT, TEST_PIN, GpioDirOut);

    DDL_ZERO_STRUCT(stcCfg);
    stcCfg.enClk = ClkRCH;          //hclk/8
    stcCfg.u32LoadVal = 0xF9Fu;     //1ms

    Clk_SysTickConfig(&stcCfg);
    SysTick_Config(stcCfg.u32LoadVal);
    
    while (1);

}





void uart_send_str(uint8_t	* ptr){
	while(*ptr){
		Uart_SendData(UARTCH1, *ptr++);
	}
}

void uart0_init(){
	uint16_t timer=0;
	uint32_t pclk=0;

	stc_uart_config_t  stcConfig;
	stc_uart_irq_cb_t stcUartIrqCb;
	stc_uart_multimode_t stcMulti;
	stc_uart_baud_config_t stcBaud;
	stc_bt_config_t stcBtConfig;


	DDL_ZERO_STRUCT(stcUartIrqCb);
	DDL_ZERO_STRUCT(stcMulti);
	DDL_ZERO_STRUCT(stcBaud);
	DDL_ZERO_STRUCT(stcBtConfig);


	Gpio_InitIO(T1_PORT,T1_PIN,GpioDirIn); 
	Gpio_InitIO(0,3,GpioDirOut);
	Gpio_SetIO(0,3,1);

	Gpio_InitIOExt(3,5,GpioDirOut,TRUE,FALSE,FALSE,FALSE);	
	Gpio_InitIOExt(3,6,GpioDirOut,TRUE,FALSE,FALSE,FALSE); 

	  //通道端口配置
    Gpio_SetFunc_UART1TX_P35();
    Gpio_SetFunc_UART1RX_P36();

    //外设时钟使能
    Clk_SetPeripheralGate(ClkPeripheralBt,TRUE);//模式0/2可以不使能
    Clk_SetPeripheralGate(ClkPeripheralUart1,TRUE);


    stcUartIrqCb.pfnRxIrqCb = RxIntCallback;
    stcUartIrqCb.pfnTxIrqCb = NULL;
    stcUartIrqCb.pfnRxErrIrqCb = ErrIntCallback;
    stcConfig.pstcIrqCb = &stcUartIrqCb;
    stcConfig.bTouchNvic = TRUE;
  

    stcConfig.enRunMode = UartMode3;//测试项，更改此处来转换4种模式测试
   

    stcMulti.enMulti_mode = UartNormal;//测试项，更改此处来转换多主机模式，mode2/3才有多主机模式

    stcConfig.pstcMultiMode = &stcMulti;

	/*
		BaudRate = ((DBUAD +1)/FCLK)/(32 * (65536 - TM))
		
	*/
    stcBaud.bDbaud = 0u;//双倍波特率功能
    stcBaud.u32Baud = 2400u;//更新波特率位置
    stcBaud.u8Mode = UartMode3; //计算波特率需要模式参数
    pclk = Clk_GetPClkFreq();
    timer=Uart_SetBaudRate(UARTCH1,pclk,&stcBaud);

    stcBtConfig.enMD = BtMode2;
    stcBtConfig.enCT = BtTimer;
    Bt_Init(TIM1, &stcBtConfig);//调用basetimer1设置函数产生波特率
    Bt_ARRSet(TIM1,timer);
    Bt_Cnt16Set(TIM1,timer);
    Bt_Run(TIM1);

    Uart_Init(UARTCH1, &stcConfig);
    Uart_EnableIrq(UARTCH1,UartRxIrq);
    Uart_ClrStatus(UARTCH1,UartRxFull);
    Uart_EnableFunc(UARTCH1,UartRx);
	
	uart_send_str("======start======\r\n");
	//while(1);
	 //Uart_SendData(UARTCH1, '1');
	 //Uart_SendData(UARTCH1, '2');
 	// Uart_SendData(UARTCH1, '3');
	 //Uart_SendData(UARTCH1, '4');
 //   while(1)
	//{
	//	CheckFlg = 0;
	//	if(u8RxFlg)
	//	{
	//		u8RxFlg = 0;
	//		if(Uart_CheckEvenOrOdd(UARTCH1,Even,u8RxData[1])!=Ok)
	//		{
	//			CheckFlg = 1;//奇偶校验出错
	//		}
	//		else
	//		{
	//			Uart_SetTb8(UARTCH1,Even,u8RxData[0]);
	//			Uart_SendData(UARTCH1,u8RxData[0]);				
	//			Uart_SetTb8(UARTCH1,Even,u8RxData[1]);
	//			Uart_SendData(UARTCH1,u8RxData[1]);
	//		}
	//	}
	//}

}


/******************************************************************************
 * Local variable definitions ('static')                                      *
 ******************************************************************************/
static  uint8_t   u8Channel;
static  uint16_t  u16ScanResult[8];
static uint32_t u32AdcResultAcc;

/*****************************************************************************
 * Function implementation - global ('extern') and local ('static')
 ******************************************************************************/

void AdcContIrqCallback(void)
{    
    //中断标志位判断和清零，已在库函数中处理Adc_IRQHandler();
  
    Adc_GetAccResult(&u32AdcResultAcc);
    Adc_ClrAccResult();  
}


void adc_test(){
    stc_adc_cfg_t             stcAdcCfg;
    stc_adc_cont_cfg_t        stcAdcContCfg;
    stc_adc_irq_t             stcAdcIrq;
    stc_adc_irq_calbakfn_pt_t stcAdcIrqCalbaks;
    
    
    DDL_ZERO_STRUCT(stcAdcCfg);
    DDL_ZERO_STRUCT(stcAdcContCfg);
    DDL_ZERO_STRUCT(stcAdcIrq);
    DDL_ZERO_STRUCT(stcAdcIrqCalbaks);
    
    Clk_SwitchTo(ClkRCL);
    Clk_SetRCHFreq(ClkFreq24Mhz);
    Clk_SwitchTo(ClkRCH);
     
    Clk_SetPeripheralGate(ClkPeripheralGpio, TRUE);              //GPIO 外设时钟使能

    
    if (Ok != Clk_SetPeripheralGate(ClkPeripheralAdcBgr, TRUE))  //ADCBGR 外设时钟使能
    {
        return ;
    }    

    Gpio_SetAnalog(2, 4, TRUE);

    
    //ADC配置
    Adc_Enable();
    M0P_BGR->CR_f.BGR_EN = 0x1u;  //BGR必须使能
    M0P_BGR->CR_f.TS_EN = 0x0u;   //内置温度传感器，视使用需求
    delay100us(1);
    
    stcAdcCfg.enAdcOpMode = AdcContMode;                //连续采样模式
    stcAdcCfg.enAdcClkSel = AdcClkSysTDiv1;             //PCLK
    stcAdcCfg.enAdcSampTimeSel = AdcSampTime8Clk;       //8个采样时钟
    // stcAdcCfg.enAdcRefVolSel = RefVolSelInBgr2p5;    //参考电压:内部2.5V(avdd>3V,SPS<=200kHz)
    stcAdcCfg.enAdcRefVolSel = RefVolSelAVDD;           //参考电压:AVDD
    // stcAdcCfg.bAdcInBufEn = TRUE;
    stcAdcCfg.bAdcInBufEn = FALSE;                      //电压跟随器如果使能，SPS采样速率 <=200K
    stcAdcCfg.enAdcTrig0Sel = AdcTrigDisable;           //ADC转换自动触发设置
    stcAdcCfg.enAdcTrig1Sel = AdcTrigDisable;
    Adc_Init(&stcAdcCfg);    
    
    stcAdcIrq.bAdcIrq = TRUE;                            //转换完成中断函数入口配置使能
    stcAdcIrq.bAdcRegCmp = FALSE;
    stcAdcIrq.bAdcHhtCmp = FALSE;
    stcAdcIrq.bAdcLltCmp = FALSE;
    stcAdcIrqCalbaks.pfnAdcContIrq = AdcContIrqCallback; //转换完成中断入口函数
    //stcAdcIrqCalbaks.pfnAdcRegIrq = AdcRegIrqCallback;
    //stcAdcIrqCalbaks.pfnAdcHhtIrq = AdcHhtIrqCallback;
    //stcAdcIrqCalbaks.pfnAdcLltIrq = AdcLltIrqCallback;
    Adc_ConfigIrq(&stcAdcIrq, &stcAdcIrqCalbaks);        //转换中断入口函数配置
    Adc_EnableIrq();                                     //中断使能
    Adc_CmpCfg(&stcAdcIrq);                              //结果比较中断使能/禁止配置
    
    
    stcAdcContCfg.enAdcContModeCh = AdcExInputCH4;      //通道0 P24
    stcAdcContCfg.u8AdcSampCnt = 0x09u;                 //P24 连续累加次数(次数 = 0x09+1)
    stcAdcContCfg.bAdcResultAccEn = TRUE;               //累加使能
    Adc_ConfigContMode(&stcAdcCfg, &stcAdcContCfg);
    
    while(1)
    {
        Adc_Start();        //ADC开始转换        
        delay1ms(1000);
    }

}


/*****************************************************************************
 * Function implementation - global ('extern') and local ('static')
 ******************************************************************************/
/**
 ******************************************************************************
 ** \brief  Main function of project
 **
 ** \return uint32_t return value, if needed
 **
 ******************************************************************************/
int32_t main(void)
{

	//led_test();
	//Debug_UartInit();
	//SysTick_Test();
	adc_test();
	uart0_init();


	while(1){
		//Uart_SendData(UARTCH1, 0x12);
		//Uart_SendData(UARTCH1, '2');

	}
}

/******************************************************************************
 * EOF (not truncated)
 ******************************************************************************/


